package com.xz.disk.controller;

import com.xz.disk.entity.MyFile;
import com.xz.disk.service.FileService;
import com.xz.disk.utils.FileUtil;
import com.xz.disk.utils.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description
 * @NAME: FileController.java
 * @author： 肖舟 XiaoZhou
 * @datetime 创建于： 2020/8/2 10:43
 */
@RestController
@RequestMapping("/file")
public class FileController {

    @Value("${path.rootPath}")
    private String rootPath;

    @Autowired
    private FileService fileService;

    @GetMapping("/getRootPath")
    public ResponseResult getRootPath() {
        return ResponseResult.SUCCESS("获取根路径", rootPath);
    }

    @GetMapping("/list")
    public ResponseResult list(HttpServletRequest request) {
        String path = request.getHeader("openPath");
        if (StringUtils.isEmpty(path)) {
            path = rootPath;
        }
        return fileService.list(path);
    }

    @GetMapping("/preview/{path}")
    public void preview(@PathVariable("path") String path, HttpServletResponse response) {
        System.out.println(path);
        path = myDecode(path);
        System.out.println(path);
        if (path == null || ObjectUtils.isEmpty(path)) {
            System.out.println("预览图片的路径为空");
            return;
        }
        FileUtil.lookImages(path, response);
    }

    /**
     * @Description: readFileStr
     * @Param: [path]
     * @return: com.xz.disk.utils.ResponseResult
     * @Author: Shawn
     * @Date: 2020/8/3 - 10:39
     */
    @GetMapping("/readFileStr")
    public ResponseResult readFileStr(HttpServletRequest request) {
        String path = request.getHeader("readPath");
        return fileService.readText(path);
    }


    // 新建文件
    @GetMapping("/touch")
    public ResponseResult touch(HttpServletRequest request) {
        String path = myDecode(request.getHeader("touchPath")).replace("^", File.separator);
        if (FileUtil.exist(path)) {
            return ResponseResult.ERROR("该目录下已存在此文件");
        }
        return FileUtil.touch(path) ? ResponseResult.SUCCESS("新建文件成功") : ResponseResult.ERROR("新建文件失败");
    }

    // 创建文件夹
    @GetMapping("/mkdir")
    public ResponseResult mkdir(HttpServletRequest request) {
        String p1 = request.getHeader("mkdirPath");
        String p2 = myDecode(p1);
        String path = p2.replace("^", File.separator);
        if (FileUtil.exist(path)) {
            return ResponseResult.ERROR("该目录下已存在此文件夹");
        }
        return FileUtil.mkdir(path) ? ResponseResult.SUCCESS("创建文件夹成功") : ResponseResult.ERROR("创建文件夹失败");
    }

    // 重新修改内容
    @GetMapping("/save")
    public ResponseResult save() {
        return null;
    }

    private String myDecode(String path) {
        try {
            path = java.net.URLDecoder.decode(path, "utf-8");
            path = path.replace("%5C%5C", File.separator).replace("%5C", File.separator).replace("%255CC", File.separator).replace("^", File.separator);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return path;
    }


    // 删除文件到回收站
    @GetMapping("/del")
    public ResponseResult del(HttpServletRequest request) {
        String p1 = request.getHeader("delPath");
        System.out.println("p1是----->" + p1);
        String p2 = myDecode(p1);
        System.out.println("p2是----->" + p2);
        String path = p2.replace("^", File.separator);
        System.out.println("path是------->" + path);
        String target = rootPath + "回收站" + File.separator;
        if (!FileUtil.isDirectory(path)) {
            String name = path.substring(path.lastIndexOf(File.separator) + 1);
            int i = 1;
            String suffix = name.substring(name.lastIndexOf("."));
            String prefix = name.substring(0, name.lastIndexOf("."));
            while (FileUtil.exist(target + prefix + suffix)) {
                prefix = prefix + i;
                i++;
            }
            System.out.println("源文件路径-------->" + path);
            System.out.println("回收站路径--------------->" + target + prefix + suffix);
            return FileUtil.move(path, target + prefix + suffix) ? ResponseResult.SUCCESS("删除文件成功") : ResponseResult.ERROR("删除文件失败");
        } else {
            String name = path.substring(path.lastIndexOf(File.separator) + 1);
            int i = 1;
            while (FileUtil.exist(target + name)) {
                name = name + i;
                i++;
            }
            return FileUtil.move(path, target + name) ? ResponseResult.SUCCESS("删除文件夹成功") : ResponseResult.ERROR("删除文件夹失败");
        }

    }

    public static void main(String[] args) {
        String path = "F:\\System Volume Information";
        String newFile = path + File.separator + "test.txt";
        FileUtil.touch(newFile);
    }


    // 批量删除文件夹到回收站
    @GetMapping("/delList")
    public ResponseResult delList(HttpServletRequest request) {
        try {
            String target = rootPath + "回收站" + File.separator;
            String delStr = request.getHeader("delStr");
            String[] delPaths = delStr.split("|");
            for (String path : delPaths) {
                String name = path.substring(0, path.lastIndexOf(File.separator));
                FileUtil.move(path, target + name);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseResult.ERROR("删除失败");
    }

    // 清空回收站
    @GetMapping("/clear")
    public ResponseResult clear() {
        try {
            String path = rootPath + "回收站" + File.separator;
            File[] files = new File(path).listFiles();
            for (File f : files) {
                FileUtil.deleteAll(f.getAbsolutePath());
            }
            return ResponseResult.SUCCESS("回收站清空成功");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.ERROR("回收站清空失败");
        }
    }

    // 重命名文件或文件夹，需要在请求头中放 要重命名的文件路径
    @GetMapping("/rename/{newName}")
    public ResponseResult rename(HttpServletRequest request, @PathVariable("/newName") String newName) {
        String path = request.getHeader("renamePath");
        return FileUtil.rename(path, newName) ? ResponseResult.SUCCESS("重命名成功") : ResponseResult.ERROR("重命名失败");
    }

    // 移动文件或文件夹到指定目录
    @GetMapping("/move")
    public ResponseResult mv(HttpServletRequest request) {
        String oldPath = myDecode(request.getHeader("oldPath"));
        String newPath = myDecode(request.getHeader("newPath"));
        return FileUtil.move(oldPath, newPath) ? ResponseResult.SUCCESS("移动成功") : ResponseResult.ERROR("移动失败");
    }

    // 下载
    @GetMapping("/downLoad/{path}")
    public void downLoad(@PathVariable("path") String path, HttpServletResponse response) {
        System.err.println(path);
        path = path.replace("^", File.separator);
        String fileName = path.substring(path.lastIndexOf(File.separator) + 1);
        path = myDecode(path);
        System.err.println(path);
        //获取要下载的文件的绝对路径
        InputStream in = null;
        OutputStream out = null;
        try {
//            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setContentType("multipart/form-data");
            //设置content-disposition响应头控制浏览器以下载的形式打开文件
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            //获取要下载的文件输入流
            in = new FileInputStream(path);
            int len = 0;
            //创建数据缓冲区
            byte[] buffer = new byte[1024];
            //通过response对象获取outputStream流
            out = response.getOutputStream();
            //将FileInputStream流写入到buffer缓冲区
            while ((len = in.read(buffer)) > 0) {
                //使用OutputStream将缓冲区的数据输出到浏览器
                out.write(buffer, 0, len);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.flush();
                    in.close();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    @PostMapping("/uploadFiles")
    public ResponseResult autoPackageUploadFiles(MultipartFile file, HttpServletRequest request) {
        String path = myDecode(request.getHeader("path"));
        if (path == null || ObjectUtils.isEmpty(path)) {
            return ResponseResult.ERROR("路径不存在");
        }
        String last = path.substring(path.length() - 1, path.length());
        System.err.println(last);
        if (!File.separator.equals(last)) {
            path += File.separator;
        }
        String absolutePath = path + file.getOriginalFilename();
        if (FileUtil.exist(absolutePath)) {
            return ResponseResult.ERROR("此文件已存在，请尝试更改文件名");
        }
        String fileName = FileUtil.uploadFile(file, path);
        if (fileName == null || "".equals(fileName)) {
            return ResponseResult.ERROR("上传失败");
        }
        return ResponseResult.SUCCESS("上传成功", fileName);
    }


    /**
     * 获取视频流
     *
     * @param response
     * @return
     * @author 肖舟
     * @Date 2020-08-03
     */
    @RequestMapping("/playVideo/{videoPath}")
    public void getVideo(HttpServletRequest request, HttpServletResponse response, @PathVariable("videoPath") String videoPath) {
        System.out.println("----------------------------------------------");
        System.out.println(videoPath);
        videoPath = myDecode(videoPath);
        System.out.println(videoPath);
        System.out.println("----------------------------------------------");

        //视频资源存储信息
//        VideoSource videoSource = videoSourceService.selectById(videoId);
        response.reset();
        //获取从那个字节开始读取文件
        String rangeString = request.getHeader("Range");

        try {
            //获取响应的输出流
            OutputStream outputStream = response.getOutputStream();
            File file = new File(videoPath);
            if (file.exists()) {
                RandomAccessFile targetFile = new RandomAccessFile(file, "r");
                long fileLength = targetFile.length();
                //播放
                if (rangeString != null) {

                    long range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));
                    //设置内容类型
                    response.setHeader("Content-Type", "video/mp4");
                    //设置此次相应返回的数据长度
                    response.setHeader("Content-Length", String.valueOf(fileLength - range));
                    //设置此次相应返回的数据范围
                    response.setHeader("Content-Range", "bytes " + range + "-" + (fileLength - 1) + "/" + fileLength);
                    //返回码需要为206，而不是200
                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                    //设定文件读取开始位置（以字节为单位）
                    targetFile.seek(range);
                } else {//下载

                    //设置响应头，把文件名字设置好
                    response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
                    //设置文件长度
                    response.setHeader("Content-Length", String.valueOf(fileLength));
                    //解决编码问题
                    response.setHeader("Content-Type", "application/octet-stream");
                }


                byte[] cache = new byte[1024 * 300];
                int flag;
                while ((flag = targetFile.read(cache)) != -1) {
                    outputStream.write(cache, 0, flag);
                }
            } else {
                String message = "file:" + file.getName() + " not exists";
                //解决编码问题
                response.setHeader("Content-Type", "application/json");
                outputStream.write(message.getBytes(StandardCharsets.UTF_8));
            }
            outputStream.flush();
            outputStream.close();

        } catch (FileNotFoundException e) {
//            e.printStackTrace();
        } catch (IOException e) {
//            e.printStackTrace();
        }
    }


    /**
     * @Description: playAudio
     * @Param: [sentences, request, response]
     * @return: void
     * @Author: Shawn
     * @Date: 2020/8/4 - 14:19
     */
    @GetMapping("/playAudio/{audioPath}")
    public void playAudio(@PathVariable("audioPath") String audioPath, HttpServletRequest request, HttpServletResponse response) throws Exception {
        //获取tomcat 路径
//        String ROOT = System.getProperty("catalina.home")+"\\webapps\\JavaWeb\\test.wav";
        System.out.println("----------------------------------------------");
        System.out.println(audioPath);
        audioPath = myDecode(audioPath);
        System.out.println(audioPath);
        System.out.println("----------------------------------------------");
        //输出 wav IO流
        try {
            response.setHeader("Content-Type", "audio/mpeg");
            File file = new File(audioPath);
            int len_l = (int) file.length();
            byte[] buf = new byte[2048];
            FileInputStream fis = new FileInputStream(file);
            OutputStream out = response.getOutputStream();
            len_l = fis.read(buf);
            while (len_l != -1) {
                out.write(buf, 0, len_l);
                len_l = fis.read(buf);
            }
            out.flush();
            out.close();
            fis.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }


    // 按文件名搜索文件
    @GetMapping("/search/{fileName}")
    public ResponseResult search(@PathVariable("fileName") String fileName) {
        if (fileName == null || "".equals(fileName)) {
            return ResponseResult.ERROR("搜索关键字为空");
        }
        return fileService.search(fileName);
    }


    @GetMapping("/getFileListByType/{type}")
    public ResponseResult getFileListByType(@PathVariable("type") String type) {
        if (type == null || "".equals(type)) {
            return ResponseResult.ERROR("分类关键字为空");
        }
        return fileService.getFileListByType(type);
    }
}
